#include "SurfacesHandler.h"
#include "LabelEquivalenceSeg.h"
#include <iostream>
#include <iterator>
#include <set>


SurfacesHandler::SurfacesHandler() : surfaces(){}

SurfacesHandler::~SurfacesHandler(){
	surfaces.~map();
}


void SurfacesHandler::processSurfaces(LabelEquivalenceSeg* seg, float3* verticeMap){
	int id;
	Surface* surf;
	int* labelMap = seg->getLabelMap();
	bool* boundaryMap = seg->getBoundaryMap();
	
	try{
		for(int i = 0; i < 480; i++){
			for(int j = 0; j < 640; j++){
				id = labelMap[j + i * 640];
				if(id > -1){

					//Insert or update surface informatoin
					surf = &surfaces.insert(std::pair<int, Surface>(id, Surface(id))).first->second;

					surf->accumulatePoints(
						verticeMap[j + i * 640].x,
						verticeMap[j + i * 640].y,
						verticeMap[j + i * 640].z,
						boundaryMap[j + i * 640]);
				}
			}
		}

		numSurfaces = surfaces.size();

	} catch (...){		//Give up; proceed to next frame
		std::cout << "Error while processing surface pool" << std::endl;
		reset();
		return;
	}

	for(std::map<int, Surface>::iterator it = surfaces.begin(); it != surfaces.end(); it++){
		it->second.compressSurface();
		/*it->second.getPlaneParameters();
		it->second.storeBoundary();*/
		
	}

}

void SurfacesHandler::reset(){
	surfaces.clear();
	numSurfaces = surfaces.size();
}

void SurfacesHandler::mergeSurfaces(SurfacesHandler* other){
	std::map<int, std::vector<int>> equivalenceList =
		std::map<int, std::vector<int>>();

	std::vector<int>* e_list;

	std::set<int> mergedList = std::set<int>();

	//std::map<int, bool> mergedList = std::map<int, bool>();

	for(std::map<int, Surface>::iterator itr = surfaces.begin();
		itr != surfaces.end(); itr++){
			for(std::map<int, Surface>::iterator itr_other = other->surfaces.begin();
				itr_other != other->surfaces.end(); itr_other++){
					if(itr->second.comparePlaneParameters(&itr_other->second)){

						//Mark to equivalence list
						equivalenceList.insert(
							std::pair<int, std::vector<int>>(
							itr->second.getSurfaceID(), std::vector<int>())).first->second.push_back(
							itr_other->second.getSurfaceID());
						
						//e_list->push_back(itr_other->second.getSurfaceID());

						//Record the merge history
						mergedList.insert(itr_other->second.getSurfaceID());
					} 
			}
	}

	for(std::map<int, Surface>::iterator itr = other->surfaces.begin();
		itr != other->surfaces.end(); itr++){
			if(mergedList.find(itr->second.getSurfaceID()) == mergedList.end()){
				//maybe a new surface is detected here


			}
	}
}

void SurfacesHandler::visualizeSurfaces(){




}
